package org.stimuliband.dsp.fft;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;

public class MainFFT {

    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        FileSystem fs = FileSystems.getDefault();
        Path file = fs.getPath(System.getProperty("user.dir"), "out_dtmf4.raw");
        FileChannel channel = FileChannel.open(file, StandardOpenOption.READ);
        System.out.println("channel.size(): " + channel.size());
        //ByteBuffer buffer = ByteBuffer.allocate((int) channel.size() / 10);
        ByteBuffer buffer = ByteBuffer.allocate(8192);
        channel.read(buffer);
        buffer.rewind();
        System.out.println("buffer.remaining(): " + buffer.remaining());



        Complex[] signal = new Complex[buffer.remaining()];
        for (int i = 0; i < signal.length; i++) {
            signal[i] = new Complex(buffer.get() & 0xFF, 0);
        }

        FFT fft = new FFT();
        Complex[] sp = fft.fft(signal);
        double[] modules = mod(sp);

        for (int i = 0; i < modules.length / 2; i++) {
            System.out.println(i + ";" + (int) modules[i]);
        }
    }

    private static double[] mod(Complex[] x) {
        double[] res = new double[x.length];
        for (int i = 0; i < res.length; i++) {
            res[i] = Math.sqrt(x[i].re() * x[i].re() + x[i].im() * x[i].im());
        }
        return res;
    }

    private static double[] derivative(double[] spectra) {
        double[] res = new double[spectra.length / 2 - 1];
        for (int i = 0; i < res.length; i++) {
            res[i] = spectra[i + 1] - spectra[i];
        }
        return res;
    }

    private static int[] findPeaks(double[] data) {
        ArrayList<Integer> peaks = new ArrayList();
        for (int i = 0; i < data.length; i++) {
            if (data[i] > 100000) {
                peaks.add(i);
            }
        }
        int[] res = new int[peaks.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = peaks.get(i);
        }
        return res;
    }
}
